﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Net;
using System.Net.Sockets;
using System.Collections;

namespace TCPServer
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();            
        }

        public String STRING_WELCOME_MESSAGE = "Welcome to join our conversation.";
        public String STRING_DISCONNECT_MESSAGE = "disconnected.";
        public String STRING_HANDUP_MESSAGE = "Server handup.";
        public Thread _incomingConnectThread;     //声明一个线程实例
        public Socket _listeningSocket;           //声明一个Socket实例
        public bool _isListening = false;
        //**
        public Socket[] _ClientSocketList;
        public int _ClientNumber;
        private byte[] MsgBuffer;//存放消息数据
        //**
        public IPEndPoint _localEndPoint;    
        public int _localPort;
        public int SetPort            
        {
            get { return _localPort; }
            set { _localPort = value; }
        }

        public delegate void IncomingInvoke(string str);

        //用来往richtextbox框中显示消息
        public void showClientMsg(string msg)
        {
            if (showinfoRichTextBox.InvokeRequired)
            {
                IncomingInvoke _myinvoke = new IncomingInvoke(showClientMsg);
                showinfoRichTextBox.Invoke(_myinvoke, new object[] { msg });
            }
            else
            {
                showinfoRichTextBox.AppendText(msg + "\r\n");
            }
        }

        public void userListAdd(string msg)
        {
            if (userListBox.InvokeRequired)
            {
                IncomingInvoke _myinvoke = new IncomingInvoke(userListAdd);
                userListBox.Invoke(_myinvoke, new object[] { msg });
            }
            else
            {
                userListBox.Items.Add(msg);
            }
        }

        public void userListRemove(string msg)
        {
            if (userListBox.InvokeRequired)
            {
                IncomingInvoke _myinvoke = new IncomingInvoke(userListRemove);
                userListBox.Invoke(_myinvoke, new object[] { msg });
            }
            else
            {
                userListBox.Items.Remove(msg);
            }
        }

        //接受客户端连接的方法
        private void RecieveAccept()
        {
            while (_isListening)
            {
                try
                {
                    _ClientSocketList[_ClientNumber] = _listeningSocket.Accept();
                    _ClientSocketList[_ClientNumber].BeginReceive(MsgBuffer, 0, MsgBuffer.Length, SocketFlags.None, new AsyncCallback(RecieveCallBack), _ClientSocketList[_ClientNumber]);

                    lock (this.userListBox)
                    {
                        userListAdd(_ClientSocketList[_ClientNumber].RemoteEndPoint.ToString());
                    }

                    DateTimeOffset now = DateTimeOffset.Now;
                    Byte[] byteDateLine = System.Text.Encoding.UTF8.GetBytes(STRING_WELCOME_MESSAGE);//将提示信息发送给客户端,并在服务端显示连接信息。
                    //showClientMsg(_ClientSocketList[_ClientNumber].RemoteEndPoint.ToString() + " is now on line at " + now.ToString("G"));
                    _ClientSocketList[_ClientNumber].Send(byteDateLine, byteDateLine.Length, 0);
                    _ClientNumber++;
                    Console.WriteLine("Client Number = " + _ClientNumber.ToString());
                }
                catch (Exception e)
                { }
            }
        }

        //回发数据给客户端
        private void RecieveCallBack(IAsyncResult AR)
        {
            try
            {
                Socket RSocket = (Socket)AR.AsyncState;
                int REnd = RSocket.EndReceive(AR);
                showClientMsg(Encoding.UTF8.GetString(MsgBuffer, 0, REnd));
                for (int i = 0; i < _ClientNumber; i++)
                {
                    if (_ClientSocketList[i].Connected)
                    {
                        if (Encoding.UTF8.GetString(MsgBuffer, 0, REnd).ToString().Contains(STRING_DISCONNECT_MESSAGE))
                        {
                            lock (this.userListBox)
                            {
                                userListRemove(RSocket.RemoteEndPoint.ToString());
                            }
                        }
                        _ClientSocketList[i].Send(MsgBuffer, 0, REnd, SocketFlags.None);
                    }
                    RSocket.BeginReceive(MsgBuffer, 0, MsgBuffer.Length, 0, new AsyncCallback(RecieveCallBack), RSocket);
                }
            }
            catch { }

        }

        private void BrocastMessage(String messageToSend)
        {
            Byte[] brocastData = Encoding.UTF8.GetBytes(messageToSend);
            showClientMsg(messageToSend);

            for (int i = 0; i < _ClientNumber; i++)
            {
                if (_ClientSocketList[i].Connected)
                {
                    _ClientSocketList[i].Send(brocastData, 0, brocastData.Length, SocketFlags.None);
                }
            }
        }
        //开始停止服务按钮
        private void startService_Click(object sender, EventArgs e)
        {
            SetPort = int.Parse(serverPortTextBox.Text.Trim());//设置端口
            _listeningSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//初始化SOCKET实例
            _listeningSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);//允许SOCKET被绑定在已使用的地址上。
            _localEndPoint = new IPEndPoint(IPAddress.Any, SetPort);//初始化终结点实例

            try
            {
                ///**
                _ClientSocketList = new Socket[53];
                _ClientNumber = 0;
                MsgBuffer = new byte[65535];//消息数据大小
                //**
                _listeningSocket.Bind(_localEndPoint);//绑定
                _listeningSocket.Listen(10);//监听
                //_listeningSocket.BeginAccept(new AsyncCallback(OnConnectRequest), _listeningSocket);//开始接受连接，异步

                ThreadStart myThreadDelegate = new ThreadStart(RecieveAccept);
                _incomingConnectThread = new Thread(myThreadDelegate);
            }
            catch (Exception ex)
            {
                showClientMsg(ex.Message);
                Console.WriteLine(ex.Message.ToString());
            }

            _isListening = true;
            _incomingConnectThread.Start();
            statuBar.Text = "服务已启动，等待客户端连接";
            sendButton.Enabled = _isListening;
            startServiceButton.Enabled = false;
            stopServiceButton.Enabled = true;
        }
        //窗口关闭时中止线程。
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            Offline();
        }

        private void Offline()
        {
            if (_isListening)
            {
                _listeningSocket.Close();
                userListBox.Items.Clear();
                for (int i = 0; i < _ClientNumber; i++)
                {
                    if (_ClientSocketList[i] != null)
                    {
                        _ClientSocketList[i].Shutdown(SocketShutdown.Both);
                        _ClientSocketList[i].Close();
                    }
                }
                _incomingConnectThread.Interrupt();
                _incomingConnectThread.Abort();
            }
            _isListening = false;
        }
        //傳送Button
        private void send_Click(object sender, EventArgs e)
        {
            String brocastMessage = "Server says: " + sendMessageTextBox.Text;
            BrocastMessage(brocastMessage);
            sendMessageTextBox.Text = "";
        }

        private void stopServiceButton_Click(object sender, EventArgs e)
        {
            BrocastMessage(STRING_HANDUP_MESSAGE);
            Offline();
            sendButton.Enabled = _isListening;
            startServiceButton.Enabled = true;
            stopServiceButton.Enabled = false;
        }
    }


}
